package ui;

import java.util.Random;

import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;

import os.MiniOS;
import os.MiniUIManager;
import controls.TitansApplicationWindow;
import controls.TitansBrowser;

public class MiniProcessPerspective extends TitansApplicationWindow
{

	private String process;

	private boolean isTerminated = false;

	private Display display;
	private TitansBrowser brwLog;
	private Text txtCommands;
	private Button btnSubmit;

	private String threadRequestedInput;

	private Random rand;

	public MiniProcessPerspective(String process, String title)
	{
		super(null, new Point(400, 400), title + " - " + process,
				"Process.ICON", null);
		this.process = process;
		rand = new Random(System.currentTimeMillis());
	}

	@Override
	protected void exitApplication()
	{
	}

	@Override
	protected void initActions()
	{
	}

	@Override
	protected void runAction(PropertyChangeEvent e)
	{
	}

	protected Control createContents(Composite parent)
	{
		parent = (Composite) super.createContents(parent);
		parent.setBackground(Display.getCurrent().getSystemColor(
				SWT.COLOR_WHITE));
		parent.setLayout(new GridLayout(2, false));

		display = Display.getCurrent();

		brwLog = new TitansBrowser(parent);
		GridData gData = new GridData(GridData.FILL_BOTH);
		gData.horizontalSpan = 2;
		brwLog.setLayoutData(gData);
		brwLog.setText("Process Starting..<br />");

		txtCommands = new Text(parent, SWT.BORDER);
		txtCommands.setEditable(false);
		txtCommands.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		btnSubmit = new Button(parent, SWT.PUSH);
		btnSubmit.setText("Submit");
		btnSubmit.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER));
		btnSubmit.setEnabled(false);

		btnSubmit.addSelectionListener(new SelectionAdapter()
		{
			public void widgetSelected(SelectionEvent e)
			{
				if (!"".equals(txtCommands.getText()))
				{
					disableInput();
					brwLog.appendText(txtCommands.getText());
					MiniUIManager.getInstance().inputReceived(process,
							threadRequestedInput, txtCommands.getText());
					txtCommands.setText("");
					txtCommands.forceFocus();
				}
			}
		});

		txtCommands.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				if (e.character == 13)
				{
					if (!"".equals(txtCommands.getText()))
					{
						disableInput();
						brwLog.appendText(txtCommands.getText());
						MiniUIManager.getInstance().inputReceived(process,
								threadRequestedInput, txtCommands.getText());
						txtCommands.setText("");
						txtCommands.forceFocus();
					}
				}
			}
		});

		return parent;
	}

	public void displayMessage(final String tid, final String message)
	{
		display.asyncExec(new Runnable()
		{
			public void run()
			{
				display.timerExec(rand.nextInt(2000), new Runnable()
				{
					public void run()
					{
						if (!brwLog.isDisposed())
						{
							if (brwLog.getText().length() > 5000)
							{
								brwLog.setText("");
							}
							brwLog.appendText(message + "<br />");
							if (tid != null)
								MiniUIManager.getInstance().messageDisplayed(
										process, tid);
						}
					}
				});
			}
		});

	}

	public void enableInput(String tid)
	{
		threadRequestedInput = tid;
		display.asyncExec(new Runnable()
		{
			public void run()
			{
				txtCommands.setEditable(true);
				btnSubmit.setEnabled(true);
				txtCommands.forceFocus();
			}
		});
	}

	public void disableInput()
	{
		display.asyncExec(new Runnable()
		{
			public void run()
			{
				txtCommands.setEditable(false);
				btnSubmit.setEnabled(false);
			}
		});
	}

	public void processTerminated()
	{
		isTerminated = true;
		displayMessage(null, "Process Terminated...");
	}

	protected void handleShellCloseEvent()
	{
		if (!isTerminated)
			MiniOS.getInstance().terminateProcess(process);
		else
			MiniUIManager.getInstance().windowClosed(process);
		super.close();
	}
}
